package com.sdhs.analyze.schedule;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sdhs.analyze.bean.DicNodeType;
import com.sdhs.analyze.bean.InfoNodeStatus;
import com.sdhs.analyze.bean.gantrymonitor.GantryMonitorTask;
import com.sdhs.analyze.bean.monitorinfo.GantryMonitorInfo;
import com.sdhs.analyze.bean.org.OrgInfo;
import com.sdhs.analyze.common.BizConstants;
import com.sdhs.analyze.service.monitor.DataTransferService;
import com.sdhs.analyze.service.monitor.DeviceService;
import com.sdhs.analyze.service.monitor.DicServiceNew;
import com.sdhs.analyze.service.monitor.EnvironmentService;
import com.sdhs.analyze.service.monitor.IndexService;
import com.sdhs.analyze.service.monitor.NetWorkService;
import com.sdhs.analyze.service.monitor.NodeStatusService;
import com.sdhs.analyze.service.monitor.OrgServiceNew;
import com.sdhs.analyze.utils.RedisUtil;
import com.sdhs.analyze.utils.StatusCheckUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 门架监测
 */
@Component
public class GantryMonitorTaskHandler {
    private static Logger logger = LoggerFactory.getLogger(GantryMonitorTaskHandler.class);
    @Autowired
    private OrgServiceNew orgService;
    @Autowired
    private DicServiceNew dicService;
    @Autowired
    private NetWorkService netWorkService;
    @Autowired
    private IndexService indexService;
    @Autowired
    private DataTransferService dataTransferService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private EnvironmentService environmentService;
    @Autowired
    private NodeStatusService nodeStatusService;
    @Autowired
    private RedisUtil redisUtil;

    private String split = "|";

    private Integer getProcessId() {
        RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
        String name = runtime.getName(); // format: "pid@hostname"
        try {
            return Integer.parseInt(name.substring(0, name.indexOf('@')));
        } catch (Exception e) {
            return -1;
        }
    }


    /**
     * 验证任务有效性
     *
     * @param task
     * @return
     */
    private boolean isValidTask(GantryMonitorTask task) {
        /* 验证任务发布时间，过长的抛弃不予处理 */
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        /* 超过逾期时间，不予处理 */
        calendar.add(Calendar.MINUTE, -1 * (task.getOverDueMinutes()));
        /* 过期监测信息不处理 */
        if (task.getCreateTime().before(calendar.getTime()) == true) {
            logger.info("监测任务过期，不处理");
            return false;
        }
        return true;
    }

    /**
     * 消费监测任务，单独group
     *
     * @param json
     */
    @KafkaListener(topics = "GANTRYMONITOR")
    public void dealGantryTask(String json) {
        /* 获取并处理监测任务 */
        GantryMonitorTask task = JSON.parseObject(json, GantryMonitorTask.class);
        if (isValidTask(task) == false) {
            return;
        }
        try {
            handleTask(task);
        } catch (Exception ex) {
            logger.error("数据分析异常！");
            logger.error(ex.getMessage(), ex);
            logger.error(json);
        }
    }

    /**
     * @param task
     */
    @Transactional(rollbackFor = Exception.class)
    public void handleTask(GantryMonitorTask task) {

        HashMap<String, OrgInfo> orgInfoMap = orgService.getGantrySystemOrgInfoMap(task.getOrgId());

        Map<String, InfoNodeStatus> infoNodeStatusMap = new HashMap<>();

        Map<String, DicNodeType> nodeTypeMap = dicService.getNodeType();

        GantryMonitorInfo gantryBackMonitorInfo = new GantryMonitorInfo();

        List<GantryMonitorInfo> gantryMonitorInfoList = new ArrayList<>();

        InfoNodeStatus gantrySystemNodeStatus = nodeStatusService.makeNodeStatus(
                nodeTypeMap.get(BizConstants.NODE_TYPE_ETC_GANTRY_SYSTEM),
                task.getOrgId(),
                orgInfoMap.get(task.getOrgId()).getOrgName()
                        + split + nodeTypeMap.get(BizConstants.NODE_TYPE_ETC_GANTRY_SYSTEM).getNodeTypeName(),
                task.getOrgId(),
                BizConstants.NODE_STATUS_UNKNOWN,
                task.getOrgId(),
                "",
                new Date(0)
        );
        for (Map.Entry<String, OrgInfo> entry : orgInfoMap.entrySet()) {
            OrgInfo orgInfo = entry.getValue();
            if (orgInfo.getOrgType() == BizConstants.ORG_TYPE_GANTRY) {

                gantryBackMonitorInfo.setGantryBackId(orgInfo.getOrgId());

                gantryBackMonitorInfo.setGantryBackName(orgInfo.getOrgName());
                /* 处理后台系统 */
                /* 后台服务器 */
                deviceService.backServerMonitor(orgInfo, infoNodeStatusMap, nodeTypeMap, gantrySystemNodeStatus, gantryBackMonitorInfo);
            } else if (orgInfo.getOrgType() == BizConstants.ORG_TYPE_GANTRY_FRONT) {

                GantryMonitorInfo gantryFrontMonitorInfo = new GantryMonitorInfo();

                gantryFrontMonitorInfo.setGantryId(orgInfo.getOrgId());

                gantryFrontMonitorInfo.setGantryName(orgInfo.getOrgName());

                gantryFrontMonitorInfo.setGantryOrderNum(orgInfo.getOrderNum());

                gantryFrontMonitorInfo.setSubCenterId(orgInfo.getSubCenterId());

                gantryFrontMonitorInfo.setCenterId(orgInfo.getCenterId());

                gantryFrontMonitorInfo.setOwnerId(orgInfo.getOwnerId());

                InfoNodeStatus frontSystemNodeStatus = nodeStatusService.makeNodeStatus(
                        nodeTypeMap.get(BizConstants.NODE_TYPE_FRONT_SYSTEM),
                        orgInfo.getOrgId(),
                        orgInfo.getOrgName() + split + nodeTypeMap.get(BizConstants.NODE_TYPE_FRONT_SYSTEM).getNodeTypeName(),
                        orgInfo.getOrgId(),
                        BizConstants.NODE_STATUS_UNKNOWN,
                        orgInfo.getOrgId(),
                        "",
                        new Date(0)
                );
                /* 网络 */
                netWorkService.networkMonitor(orgInfo, infoNodeStatusMap, nodeTypeMap, frontSystemNodeStatus, gantryFrontMonitorInfo);
                /* 交易数据传输 */
                dataTransferService.tradeTransferMonitor(orgInfo, infoNodeStatusMap, nodeTypeMap, frontSystemNodeStatus, gantryFrontMonitorInfo);
                /* 牌识数据传输 */
                dataTransferService.vehTransferMonitor(orgInfo, infoNodeStatusMap, nodeTypeMap, frontSystemNodeStatus, gantryFrontMonitorInfo);
                /* 动环 */
                environmentService.environmentMonitor(orgInfo, infoNodeStatusMap, nodeTypeMap, frontSystemNodeStatus, gantryFrontMonitorInfo);
                /* 前端工控机 */
                deviceService.frontServerMonitor(orgInfo, infoNodeStatusMap, nodeTypeMap, frontSystemNodeStatus, gantryFrontMonitorInfo);
                /* 牌识设备 */
                deviceService.cameraMonitor(orgInfo, infoNodeStatusMap, nodeTypeMap, frontSystemNodeStatus, gantryFrontMonitorInfo);
                /* RSU */
                deviceService.rsuMonitor(orgInfo, infoNodeStatusMap, nodeTypeMap, frontSystemNodeStatus, gantryFrontMonitorInfo);
                /* 天线头 */
                deviceService.antennalMonitor(orgInfo, infoNodeStatusMap, nodeTypeMap, frontSystemNodeStatus, gantryFrontMonitorInfo);
                /* 机柜 */
                deviceService.cabinetMonitor(orgInfo, infoNodeStatusMap, nodeTypeMap, frontSystemNodeStatus, gantryFrontMonitorInfo);
                /* 运行指标 */
                indexService.indexMonitor(orgInfo, infoNodeStatusMap, nodeTypeMap, frontSystemNodeStatus, gantryFrontMonitorInfo);
                /* 处理前端系统 */
                StatusCheckUtils.checkParentNodeStatus(
                        frontSystemNodeStatus.getStatus(),
                        frontSystemNodeStatus.getStatusCheckTime(),
                        gantrySystemNodeStatus);

                /* 前端系统 */
                infoNodeStatusMap.put(frontSystemNodeStatus.getKey(), frontSystemNodeStatus);

                gantryFrontMonitorInfo.setGantryStatus(frontSystemNodeStatus.getStatus());

                gantryMonitorInfoList.add(gantryFrontMonitorInfo);
            }
        }
        /* 处理门架系统 */
        infoNodeStatusMap.put(gantrySystemNodeStatus.getKey(), gantrySystemNodeStatus);
        /* 处理完成，保存结果 */
        nodeStatusService.saveInfoNodeStatusAndTrace(task.getOrgId(), infoNodeStatusMap, nodeTypeMap);
        /* 缓存 */
        for (GantryMonitorInfo gantryMonitorInfo : gantryMonitorInfoList) {

            String gantryMonitorInfoKey = BizConstants.REDIS_KEY_PRE_GANTRY_MONITOR_INFO + ":" + gantryMonitorInfo.getGantryId();

            gantryMonitorInfo.setGantryBackId(gantryBackMonitorInfo.getGantryBackId());

            gantryMonitorInfo.setGantryBackName(gantryBackMonitorInfo.getGantryBackName());

            gantryMonitorInfo.setBackServer(gantryBackMonitorInfo.getBackServer());

            int deviceStatus = gantryMonitorInfo.getDevice().getStatus();

            if (deviceStatus < gantryBackMonitorInfo.getDevice().getStatus()) {

                gantryMonitorInfo.getDevice().setStatus(gantryBackMonitorInfo.getDevice().getStatus());
            }

            gantryMonitorInfo.setGantryStatus(gantryMonitorInfo.getGantryStatus() >= gantryBackMonitorInfo.getBackServer().getStatus() ?
                    gantryMonitorInfo.getGantryStatus() : gantryBackMonitorInfo.getBackServer().getStatus());

            redisUtil.set(gantryMonitorInfoKey, JSONObject.toJSONString(gantryMonitorInfo));
        }
    }
}
